package com.pan.test.component;

import com.pan.test.entity.constants.Constants;
import com.pan.test.entity.dto.DownloadFileDto;
import com.pan.test.entity.dto.SysSettingsDto;
import com.pan.test.entity.dto.UserSpaceDto;
import com.pan.test.entity.po.FileInfo;
import com.pan.test.entity.po.UserInfo;
import com.pan.test.entity.query.FileInfoQuery;
import com.pan.test.entity.query.UserInfoQuery;
import com.pan.test.mappers.FileInfoMapper;
import com.pan.test.mappers.UserInfoMapper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component("redisComponent")
@SuppressWarnings("unchecked")
public class RedisComponent {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private FileInfoMapper<FileInfo, FileInfoQuery> fileInfoMapper;

    /**
     * 获取系统设置
     *
     * @return
     */
    public SysSettingsDto getSysSettingsDto() {
        // 从Redis中获取系统设置信息
        SysSettingsDto sysSettingsDto = (SysSettingsDto) redisUtils.get(Constants.REDIS_KEY_SYS_SETTING);
        // 如果Redis中没有系统设置信息，则创建一个新的系统设置信息对象
        if (sysSettingsDto == null) {
            sysSettingsDto = new SysSettingsDto();
            // 将新的系统设置信息对象存入Redis
            redisUtils.set(Constants.REDIS_KEY_SYS_SETTING, sysSettingsDto);
        }
        // 返回系统设置信息对象
        return sysSettingsDto;
    }

    /**
     * 保存设置
     *
     * @param sysSettingsDto
     */
    public void saveSysSettingsDto(SysSettingsDto sysSettingsDto) {
        // 将SysSettingsDto对象保存到Redis中，键为Constants.REDIS_KEY_SYS_SETTING
        redisUtils.set(Constants.REDIS_KEY_SYS_SETTING, sysSettingsDto);
    }

    public void saveDownloadCode(String code, DownloadFileDto downloadFileDto) {
        // 将DownloadFileDto对象保存到Redis中，键为Constants.REDIS_KEY_DOWNLOAD + code，过期时间为Constants.REDIS_KEY_EXPIRES_FIVE_MIN
        redisUtils.setex(Constants.REDIS_KEY_DOWNLOAD + code, downloadFileDto, Constants.REDIS_KEY_EXPIRES_FIVE_MIN);
    }

    public DownloadFileDto getDownloadCode(String code) {
        // 从Redis中获取DownloadFileDto对象，键为Constants.REDIS_KEY_DOWNLOAD + code
        return (DownloadFileDto) redisUtils.get(Constants.REDIS_KEY_DOWNLOAD + code);
    }


    /**
     * 获取用户使用的空间
     *
     * @param userId
     * @return
     */
    public UserSpaceDto getUserSpaceUse(String userId) {
        // 从redis中获取用户空间使用情况
        UserSpaceDto spaceDto = (UserSpaceDto) redisUtils.get(Constants.REDIS_KEY_USER_SPACE_USE + userId);
        // 如果redis中没有该用户的空间使用情况
        if (null == spaceDto) {
            // 创建一个新的UserSpaceDto对象
            spaceDto = new UserSpaceDto();
            // 从数据库中获取该用户的空间使用情况
            Long useSpace = this.fileInfoMapper.selectUseSpace(userId);
            // 设置用户空间使用情况
            spaceDto.setUseSpace(useSpace);
            // 设置用户总空间
            spaceDto.setTotalSpace(getSysSettingsDto().getUserInitUseSpace() * Constants.MB);
            // 将用户空间使用情况存入redis，并设置过期时间为Constants.REDIS_KEY_EXPIRES_DAY
            redisUtils.setex(Constants.REDIS_KEY_USER_SPACE_USE + userId, spaceDto, Constants.REDIS_KEY_EXPIRES_DAY);
        }
        // 返回用户空间使用情况
        return spaceDto;
    }

    /**
     * 保存已使用的空间
     *
     * @param userId
     */
    // 保存用户空间使用情况
public void saveUserSpaceUse(String userId, UserSpaceDto userSpaceDto) {
        // 使用redisUtils工具类，将用户空间使用情况保存到redis中，并设置过期时间为Constants.REDIS_KEY_EXPIRES_DAY
        redisUtils.setex(Constants.REDIS_KEY_USER_SPACE_USE + userId, userSpaceDto, Constants.REDIS_KEY_EXPIRES_DAY);
    }

    // 根据用户ID重置用户空间使用情况
public UserSpaceDto resetUserSpaceUse(String userId) {
        // 创建一个UserSpaceDto对象
        UserSpaceDto spaceDto = new UserSpaceDto();
        // 根据用户ID查询用户已使用空间
        Long useSpace = this.fileInfoMapper.selectUseSpace(userId);
        // 设置用户已使用空间
        spaceDto.setUseSpace(useSpace);

        // 根据用户ID查询用户信息
        UserInfo userInfo = this.userInfoMapper.selectByUserId(userId);
        // 设置用户总空间
        spaceDto.setTotalSpace(userInfo.getTotalSpace());
        // 将用户空间使用情况存入Redis，并设置过期时间为Constants.REDIS_KEY_EXPIRES_DAY
        redisUtils.setex(Constants.REDIS_KEY_USER_SPACE_USE + userId, spaceDto, Constants.REDIS_KEY_EXPIRES_DAY);
        // 返回用户空间使用情况
        return spaceDto;
    }

    //保存文件临时大小
    public void saveFileTempSize(String userId, String fileId, Long fileSize) {
        //获取当前文件临时大小
        Long currentSize = getFileTempSize(userId, fileId);
        //将当前文件临时大小与传入的文件大小相加，并设置到Redis中，过期时间为1小时
        redisUtils.setex(Constants.REDIS_KEY_USER_FILE_TEMP_SIZE + userId + fileId, currentSize + fileSize, Constants.REDIS_KEY_EXPIRES_ONE_HOUR);
    }

    // 根据用户ID和文件ID获取文件临时大小
public Long getFileTempSize(String userId, String fileId) {
        // 从Redis中获取用户文件临时大小
        Long currentSize = getFileSizeFromRedis(Constants.REDIS_KEY_USER_FILE_TEMP_SIZE + userId + fileId);
        // 返回文件临时大小
        return currentSize;
    }

    // 从Redis中获取文件大小
private Long getFileSizeFromRedis(String key) {
        // 从Redis中获取key对应的值
        Object sizeObj = redisUtils.get(key);
        // 如果值为空，则返回0
        if (sizeObj == null) {
            return 0L;
        }
        // 如果值为Integer类型，则将其转换为Long类型并返回
        if (sizeObj instanceof Integer) {
            return ((Integer) sizeObj).longValue();
        // 如果值为Long类型，则直接返回
        } else if (sizeObj instanceof Long) {
            return (Long) sizeObj;
        }

        // 如果值既不是Integer类型也不是Long类型，则返回0
        return 0L;
    }
}
